#pragma once

#include "risk.h"
#include <string>
#include <memory>
#include <vector>
#include <fstream>
#include <unordered_map>
#include "json.hpp"

namespace hft {

struct ContractConfig {
    std::string symbol;
    std::string description;
    double multiplier;
    double min_tick;
    double margin_ratio;
};

class ConfigLoader {
public:
    static ConfigLoader& getInstance() {
        static ConfigLoader instance;
        return instance;
    }

    bool loadConfig(const std::string& filename) {
        try {
            std::ifstream file(filename);
            if (!file.is_open()) {
                return false;
            }
            config_ = nlohmann::json::parse(file);
            return true;
        } catch (const std::exception& e) {
            return false;
        }
    }

    nlohmann::json getNode(const std::string& path) const {
        return config_[path];
    }

    // 加载风险配置
    bool loadRiskConfig(const std::string& config_file) {
        try {
            std::ifstream file(config_file);
            if (!file.is_open()) {
                std::cerr << "无法打开配置文件: " << config_file << std::endl;
                return false;
            }
            
            nlohmann::json j;
            file >> j;
            
            // 加载全局限制
            auto& global = j["global_limits"];
            global_limits_.max_position_value = global["max_position_value"];
            global_limits_.max_drawdown = global["max_drawdown"];
            global_limits_.max_daily_loss = global["max_daily_loss"];
            global_limits_.max_order_size = global["max_order_size"];
            global_limits_.max_leverage = global["max_leverage"];
            
            // 加载合约限制
            auto& contracts = j["contract_limits"];
            for (auto it = contracts.begin(); it != contracts.end(); ++it) {
                ContractRiskLimits limits;
                limits.max_position_value = it.value()["max_position_value"];
                limits.max_order_size = it.value()["max_order_size"];
                limits.max_leverage = it.value()["max_leverage"];
                contract_limits_[it.key()] = limits;
            }
            
            return true;
        } catch (const std::exception& e) {
            std::cerr << "加载配置文件失败: " << e.what() << std::endl;
            return false;
        }
    }
    
    // 加载合约配置
    bool loadContractConfig(const std::string& config_file) {
        try {
            std::ifstream file(config_file);
            if (!file.is_open()) {
                std::cerr << "无法打开配置文件: " << config_file << std::endl;
                return false;
            }
            
            nlohmann::json j;
            file >> j;
            
            contracts_.clear();
            for (const auto& contract : j["contracts"]) {
                ContractConfig config;
                config.symbol = contract["symbol"];
                config.description = contract["description"];
                config.multiplier = contract["multiplier"];
                config.min_tick = contract["min_tick"];
                config.margin_ratio = contract["margin_ratio"];
                contracts_.push_back(config);
            }
            
            return true;
        } catch (const std::exception& e) {
            std::cerr << "加载合约配置失败: " << e.what() << std::endl;
            return false;
        }
    }
    
    // 获取全局风险限制
    const RiskLimits& getGlobalLimits() const { return global_limits_; }
    
    // 获取合约风险限制
    const std::unordered_map<std::string, ContractRiskLimits>& getContractLimits() const {
        return contract_limits_;
    }
    
    // 获取特定合约的风险限�?
    ContractRiskLimits getContractLimits(const std::string& symbol) const {
        auto it = contract_limits_.find(symbol);
        if (it != contract_limits_.end()) {
            return it->second;
        }
        return ContractRiskLimits();  // 返回默认�?
    }
    
    // 获取所有合约配�?
    const std::vector<ContractConfig>& getContracts() const {
        return contracts_;
    }
    
    // 获取特定合约的配�?
    ContractConfig getContractConfig(const std::string& symbol) const {
        for (const auto& config : contracts_) {
            if (config.symbol == symbol) {
                return config;
            }
        }
        return ContractConfig();  // 返回默认�?
    }

private:
    ConfigLoader() = default;
    ~ConfigLoader() = default;
    ConfigLoader(const ConfigLoader&) = delete;
    ConfigLoader& operator=(const ConfigLoader&) = delete;
    
    RiskLimits global_limits_;
    std::unordered_map<std::string, ContractRiskLimits> contract_limits_;
    std::vector<ContractConfig> contracts_;
    nlohmann::json config_;
};

} // namespace hft 
